#include "Window.h"

Window::Window():ZWidget()
{
	this->setGeometry(0, 0, 240, 320);
	pixbuffer = QPixmap(240, 320);
	initB2World();
	initSprites();
	//updateOneFrame();
	timerID=0;
	if(!timerID)
		timerID = startTimer(1000 / 60.0);
}
Window::~Window()
{
	delete boxdown;
	delete boxleft;
	delete boxright;
	delete boxObject;
	delete ell;
}
void Window::initB2World()
{
	// Define world, gravity
	b2AABB worldAABB;
	worldAABB.lowerBound.Set(-60.0f, -80.0f);
	worldAABB.upperBound.Set(60.0f, 80.0f);
	bool doSleep = true;
	b2Vec2 gravity(0.0f, -10.0f);
	_world = new b2World(worldAABB, gravity, doSleep);
	
	//down ground
	b2BodyDef bodyDef;
	b2PolygonDef shapeDef;
	bodyDef.position.Set(0.0f, -75.0f);
	shapeDef.SetAsBox(60.f, 5.0f);
	groundBody = _world->CreateBody(&bodyDef);
	groundBody->CreateShape(&shapeDef);

	//left block
	bodyDef.position.Set(-55.0f, -35.0f);
	shapeDef.SetAsBox(5.0f, 35.0f);
	b2Body *leftBody = _world->CreateBody(&bodyDef);
	leftBody->CreateShape(&shapeDef);

	//right block
	bodyDef.position.Set(55.0f, -35.0f);
	shapeDef.SetAsBox(5.0f, 35.0f);
	b2Body *rightBody = _world->CreateBody(&bodyDef);
	rightBody->CreateShape(&shapeDef);


	// a rect box object
	b2BodyDef mybodyDef;
	mybodyDef.position.Set(0.0f, 0.0f);
	mybodyDef.angle = PI/5;

	boxBody = _world->CreateBody(&mybodyDef);

	b2PolygonDef myshapeDef;
	myshapeDef.density = 1.0f;
	myshapeDef.friction = 0.2f;
	myshapeDef.SetAsBox(5.0f, 5.0f);
	boxBody->CreateShape(&myshapeDef);
	// set the default mass
	boxBody->SetMassFromShapes();

	// another rect box object
	mybodyDef.position.Set(1.0f, 15.0f);
	mybodyDef.angle = PI/4;

	boxBody2 = _world->CreateBody(&mybodyDef);

	myshapeDef.density = 1.0f;
	myshapeDef.friction = 0.2f;
	myshapeDef.SetAsBox(5.0f, 5.0f);
	boxBody2->CreateShape(&myshapeDef);
	// set the default mass
	boxBody2->SetMassFromShapes();

}

void Window::initSprites()
{
	mlist.clear();
	boxdown = new BoxSprite(120, 310, 240, 20, true);
	boxdown->setColor(CRED);
	boxdown->setAngD(0);
	mlist.append(boxdown);

	boxleft = new BoxSprite(10, 230, 20, 140, true);
	boxleft->setColor(CBLUE);
	boxleft->setAngD(0);
	mlist.append(boxleft);

	boxright = new BoxSprite(230, 230, 20, 140, true);
	boxright->setColor(CBLUE);
	boxright->setAngD(0);
	mlist.append(boxright);

	boxObject = new BoxSprite(120, 160, 20, 20, true);
	boxObject->setColor(CGREEN);
	boxObject->setAngD(0);
	mlist.append(boxObject);

	boxObject2 = new BoxSprite(120, 160, 20, 20, true);
	boxObject2->setColor(CRED);
	boxObject2->setAngD(0);
	mlist.append(boxObject2);

	ell = new EllipseSprite(50, 160, 30, 30, false);
	ell->setColor(CRED);
	ell->setAngD(30);
	mlist.append(ell);
	
	QPointArray pa = QPointArray(3);
	pa[0] = QPoint(0, -20);
	pa[1] = QPoint(20, 20);
	pa[2] = QPoint(-20, 20);
	poly = new PolySprite(120, 60, pa, false);
	poly->setColor(CBLUE);
	poly->setAngD(30);
	mlist.append(poly);
}
void Window::updateOneFrame()
{
	_world->Step(1.0f/30.0f, 10);

	b2Vec2 pos = boxBody->GetPosition();
	float ang = boxBody->GetAngle();
	boxObject->setPosition(120+pos.x*2, 160-pos.y*2);
	printf("Pos(%f,%f)--Pos(%d,%d)\n", pos.x, pos.y,
			120+pos.x*2, (int)(160-pos.y*2));
	boxObject->setAng(-ang);

	b2Vec2 pos2 = boxBody2->GetPosition();
	float ang2 = boxBody2->GetAngle();
	boxObject2->setPosition(120+pos2.x*2, 160-pos2.y*2);
	boxObject2->setAng(-ang2);

	this->repaint();
}
void Window::timerEvent(QTimerEvent *e)
{
	if(e->timerId() == timerID)
	{
		updateOneFrame();
	}
}
void Window::paintEvent(QPaintEvent *e)
{
	pixbuffer.fill(CWHITE);
	QPainter *p = new QPainter();
	p->begin(&pixbuffer);
	p->setPen(CBLACK);
	p->drawLine(120, 0, 120, 320);
	p->drawLine(0, 160, 240, 160);
	p->end();
	delete p;
	for(unsigned int i=0; i<mlist.count(); i++)
	{
		Sprite * ms = (Sprite *)mlist[i];
		ms->paint(pixbuffer);
	}
	bitBlt(this,0,0,&pixbuffer);
}

